package com.kaka.jsonmap.core.evaluator;

import com.jayway.jsonpath.JsonPath;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.GroovyShell;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
public class GroovyEvaluator implements ExpressionEvaluator {
    private static final String GROOVY_PREFIX = "groovy(";

    private static final String JSON_PATH_CLASS = JsonPath.class.getName();

    private final GroovyShell groovyShell = new GroovyShell();


    @Override
    public boolean supports(String expressionType) {
        return expressionType.startsWith(GROOVY_PREFIX);
    }

    @Override
    public Object evaluate(String expression, Map<String, Object> context) {
        try {
            expression = expression.substring(GROOVY_PREFIX.length(), expression.length() - 1);
            String processedExpression = expression.replaceAll("jsonPath\\((\\$\\.[^)]+)\\)",
                            JSON_PATH_CLASS + ".read(source, '$1')");
            groovyShell.setVariable("source", context);
            Object result = groovyShell.evaluate(processedExpression);
            if (result instanceof Number) {
                double doubleValue = ((Number) result).doubleValue();
                if (doubleValue == Math.floor(doubleValue)) {
                    return (long) doubleValue;
                }
            }
            return result;
        } catch (Throwable e) {
            log.error("Failed to evaluate expression:{} ", expression, e);
            throw new GroovyRuntimeException(e);
        }
    }
}
